package com.kayeah82.application.avatar.qq.initializer;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

import java.io.File;
import java.util.Properties;

/**
 * 程序目录结构。
 *
 * @author kayeah82
 */
class HomeStructure {

    private final static String ENV_DELIMITER = "_";
    private final static String PROPERTY_DELIMITER = ".";
    private final static String APP_BASE = "AVATAR";

    private final static String HOME_ENV = APP_BASE + ENV_DELIMITER + "HOME";
    private final static String HOME_PROPERTY = APP_BASE.toLowerCase() + PROPERTY_DELIMITER + "home";

    private final static String CONF_PROPERTY = APP_BASE.toLowerCase() + PROPERTY_DELIMITER + "conf";
    private final static String DATA_PROPERTY = APP_BASE.toLowerCase() + PROPERTY_DELIMITER + "data";
    private final static String LOGS_PROPERTY = APP_BASE.toLowerCase() + PROPERTY_DELIMITER + "logs";
    private final static String TEMP_PROPERTY = APP_BASE.toLowerCase() + PROPERTY_DELIMITER + "temp";

	private File root;
	private String[] artifactIds;

    private HomeStructure(File root, String[] artifactIds) {
        this.root = root;
        this.artifactIds = artifactIds;
    }

    private HomeStructure(File root) {
        this.root = root;
    }

    /**
	 * 根据系统环境变量或系统属性（优先）指向的根目录建立程序目录结构。
	 *
	 * @return 程序目录结构
	 */
	static HomeStructure env(String... artifactIds) {
	    String homeProperty = getHomeProperty(artifactIds), homeEnv = getHomeEnv(artifactIds);

        String path = System.getProperty(homeProperty.toUpperCase(), System.getenv(homeEnv.toLowerCase()));
        if (StringUtils.isEmpty(path)) {
            path = System.getProperty(homeProperty.toLowerCase(), System.getenv(homeEnv.toUpperCase()));
        }
        if (StringUtils.isEmpty(path)) {
            path = System.getProperty(homeProperty.toLowerCase(), System.getenv(homeEnv.toLowerCase()));
        }
        if (StringUtils.isEmpty(path)) {
            path = System.getProperty(homeProperty.toUpperCase(), System.getenv(homeEnv.toUpperCase()));
        }

        File root = new File(path);
		return hasArtifactIds(artifactIds) ? new HomeStructure(root, artifactIds) : new HomeStructure(root);
	}

    static HomeStructure env() {
        return env(ArrayUtils.EMPTY_STRING_ARRAY);
    }

	/**
	 * 获得程序根目录。
	 *
	 * @return 程序根目录
	 */
    File getHomeDirectory() {
        return root;
    }

    /**
	 * 将程序目录结构导出到属性中。
	 *
	 * @param properties 属性集
	 */
	void dumpStructure(Properties properties) {
        properties.setProperty(joinArtifactIds(CONF_PROPERTY, PROPERTY_DELIMITER, "conf", this.artifactIds), this.getConfDirectory().getPath());
        properties.setProperty(joinArtifactIds(DATA_PROPERTY, PROPERTY_DELIMITER, "data", this.artifactIds), this.getDataDirectory().getPath());
        properties.setProperty(joinArtifactIds(LOGS_PROPERTY, PROPERTY_DELIMITER, "logs", this.artifactIds), this.getLogsDirectory().getPath());
        properties.setProperty(joinArtifactIds(TEMP_PROPERTY, PROPERTY_DELIMITER, "temp", this.artifactIds), this.getTempDirectory().getPath());
	}

	/**
	 * 获得程序配置目录。
	 *
	 * @return 程序配置目录
	 */
	File getConfDirectory() {
		return new File(this.getHomeDirectory(), "conf");
	}

	/**
	 * 获得程序数据目录。
	 *
	 * @return 程序数据目录
	 */
    File getDataDirectory() {
		return new File(this.getHomeDirectory(), "data");
	}

	/**
	 * 获得程序日志目录。
	 *
	 * @return 程序日志目录
	 */
    File getLogsDirectory() {
		return new File(this.getHomeDirectory(), "logs");
	}

	/**
	 * 获得程序临时目录。
	 *
	 * @return 程序临时目录
	 */
    File getTempDirectory() {
		return new File(this.getHomeDirectory(), "temp");
	}

    private static String getHomeEnv(String... artifactIds) {
        return joinArtifactIds(HOME_ENV, ENV_DELIMITER, "HOME", artifactIds);
	}

    private static String getHomeProperty(String... artifactIds) {
        return joinArtifactIds(HOME_PROPERTY, PROPERTY_DELIMITER, "home", artifactIds);
    }

    private static String joinArtifactIds(String def, String delimiter, String type, String[] artifactIds) {
        if (!hasArtifactIds(artifactIds)) {
            return def;
        }
        StringBuilder builder = new StringBuilder();
        builder.append(APP_BASE);
        builder.append(delimiter);
        for (String artifactId : artifactIds) {
            builder.append(artifactId.toLowerCase());
            builder.append(delimiter);
        }
        builder.append(type);
        return builder.toString();
    }

    private static boolean hasArtifactIds(String[] artifactIds) {
        return artifactIds != null && artifactIds.length > 0;
    }

}
